﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using BinarySerialization;

namespace EditMode
{
    /// <summary> 
    /// Edit lyrics instruction. 
    /// </summary>
    [Serializable]
    public class EditLyric
    {
        [FieldOrder(0)]
        public uint Time { get; set; }

        [FieldOrder(1)]
        public byte Selectable { get; set; } = 0x01;

        [FieldOrder(2)]
        public ColorID ColorID { get; set; }

        [FieldOrder(3)]
        public ushort Unknonw0 { get; set; }

        [FieldOrder(4)]
        [FieldLength(42)]
        public byte[] lyrics = new byte[42];

        [Ignore]
        public string Lyrics
        {
            get
            {
                return Utilities.GetString(lyrics, Encoding.Unicode);
            }
            set
            {
                lyrics = Utilities.GetBytes(value, 42, Encoding.Unicode);
            }
        }

        [FieldOrder(5)]
        public ushort Unknown1 { get; set; }

        [FieldOrder(6)]
        public byte Alpha { get; set; }

        [FieldOrder(7)]
        public byte R { get; set; } = 0xFF;

        [FieldOrder(8)]
        public byte G { get; set; } = 0xFF;

        [FieldOrder(9)]
        public byte B { get; set; } = 0xFF;

        [FieldOrder(10)]
        public uint Duration { get; set; } = 0x02;

        [FieldOrder(11)]
        [FieldLength(32)]
        public byte[] Space { get; set; } = new byte[32];

        public override string ToString()
        {
            return Lyrics;
        }

        public EditLyric() { }

        public EditLyric(string lyrics, uint time = 0, uint length = 2, byte color = 0)
        {
            Lyrics = lyrics;
            Time = time; Duration = length; ColorID = (ColorID)color;
        }

        public static List<EditLyric> ReadTextFile(string inputFile, uint interval = 120, uint length = 20, byte color = 0)
        {
            var editLyrics = new List<EditLyric>();
            var allLines = File.ReadAllLines(inputFile);
            uint time = 0;
            foreach (var line in allLines)
            {
                editLyrics.Add( new EditLyric(line, time, length, color) );
                time += interval;
            }
            return editLyrics;
        }
        
        public static void WriteLyricsToFile(List<EditLyric> editLyrics, string filePath)
        {
            var writer = new StreamWriter(new FileStream(filePath, FileMode.Create));
            int i = 0, pv = 0;
            foreach (var lyric in editLyrics)
            {
                string line = string.Format("pv_{2:000}.lyric.{1:000}={0}", lyric.ToString(), i, pv);
                writer.WriteLine(lyric.ToString());
                i++;
            }
            writer.Flush();
            writer.BaseStream.Dispose();
        }
    }

    public class KysEditLyric
    {
        [FieldOrder(0)]
        public uint Time { get; set; }

        [FieldOrder(1)]
        public byte Selectable { get; set; } = 0x01;

        [FieldOrder(2)]
        public ColorID ColorID { get; set; }

        [FieldOrder(3)]
        public ushort Unknown { get; set; }

        [FieldOrder(4)]
        public byte Alpha { get; set; }

        [FieldOrder(5)]
        public byte R { get; set; } = 0xFF;

        [FieldOrder(6)]
        public byte G { get; set; } = 0xFF;

        [FieldOrder(7)]
        public byte B { get; set; } = 0xFF;

        [FieldOrder(8)]
        public uint Duration { get; set; } = 0x02;

        [FieldOrder(9)]
        [FieldLength(88)]
        public byte[] lyrics = new byte[88];

        [Ignore]
        public string Lyrics
        {
            get
            {
                return Utilities.GetString(lyrics, Encoding.Unicode);
            }
            set
            {
                lyrics = Utilities.GetBytes(value, 42, Encoding.Unicode);
            }
        }

        [FieldOrder(10)]
        [FieldLength(32)]
        public byte[] Space { get; set; } = new byte[32];

        public KysEditLyric()
        {

        }

        public KysEditLyric(EditLyric editLyric)
        {
            Time = editLyric.Time;
            Selectable = editLyric.Selectable;
            ColorID = editLyric.ColorID;
            Unknown = editLyric.Unknonw0;
            Alpha = editLyric.Alpha;
            R = editLyric.R;
            G = editLyric.G;
            B = editLyric.B;
            Duration = editLyric.Duration;
            Lyrics = editLyric.Lyrics;
        }

        public EditLyric GetEditLyric()
        {
            return new EditLyric()
            {
                Time = Time,
                Selectable = Selectable,
                ColorID = ColorID,
                Unknonw0 = Unknown,
                Lyrics = Lyrics,
                Alpha = Alpha,
                R = R,
                G = G,
                B = B,
                Duration = Duration,
            };
        }
    }
}
